package com.macasa.panel.entity.impl;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Version;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import org.hibernate.annotations.ForeignKey;

import com.google.common.base.Objects;
import com.macasa.panel.common.utils.CastHelpers;
import com.macasa.panel.entity.api.AbstractModel;
import com.macasa.panel.entity.api.IApacheService;
import com.macasa.panel.entity.api.IDomain;
import com.macasa.panel.entity.api.IPowerDnsServiceMaster;
import com.macasa.panel.entity.api.IPowerDnsServiceSlave;
import com.macasa.panel.entity.api.IPureFtpdService;
import com.macasa.panel.entity.api.ISubDomain;

@Entity
@Table(name = "domain")
@SequenceGenerator(name = "Domain_SEQ", sequenceName = "DomainIdSeq", initialValue = 1)
@Getter
@Setter
@ToString
public class Domain extends AbstractModel<Integer> implements IDomain {

	/**
	 * The Constant serialVersionUID
	 */
	@Version
	private static final long		serialVersionUID	= -5414886086964120817L;

	@Id
	@Column(name = "domain_id", nullable = false)
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "Domain_SEQ")
	private Integer					id;

	@Column(name = "domain_name", nullable = false)
	private String					domainName;

	@Column(name = "disk_quota", nullable = true)
	private Integer					diskQuota;

	@Column(name = "band_width", nullable = true)
	private String					bandWidth;

	@Column(name = "min_bandwidth", nullable = true)
	private String					minBandwidth;

	@Column(name = "max_connection", nullable = true)
	private String					maxConnection;

	@Column(name = "max_email", nullable = true)
	private Integer					maxEmail;

	@Column(name = "max_email_alias", nullable = true)
	private Integer					maxEmailAlias;

	@Column(name = "max_sub_domain", nullable = true)
	private Integer					maxSubDomain;

	@Column(name = "max_ftp", nullable = true)
	private Integer					maxFtp;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = com.macasa.panel.entity.impl.ApacheService.class)
	@JoinColumn(name = "fk_apache_service", nullable = true)
	private IApacheService			apacheService;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = com.macasa.panel.entity.impl.PureFtpdService.class)
	@JoinColumn(name = "fk_pure_ftpd_service", nullable = true)
	private IPureFtpdService		pureFtpdService;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = com.macasa.panel.entity.impl.PowerDnsServiceMaster.class)
	@JoinColumn(name = "fk_power_dns_service_master", nullable = true)
	private IPowerDnsServiceMaster	powerDnsServiceMaster;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = com.macasa.panel.entity.impl.PowerDnsServiceSlave.class)
	@JoinColumn(name = "fk_power_dns_service_slave", nullable = true)
	private IPowerDnsServiceSlave	powerDnsServiceSlave;

	@Column(name = "catchall_email", nullable = true)
	private Integer					catchallEmail;

	@OneToMany(mappedBy = "domain", cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = com.macasa.panel.entity.impl.SubDomain.class)
	@ForeignKey(name = "fk_sub_domain_01")
	private List<ISubDomain>		subDomains;

	@Override
	public boolean equals(final Object obj) {

		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Domain)) {
			return false;
		}

		final Domain other = CastHelpers.cast(obj, Domain.class);

		return Objects.equal(this.id, other.id) && Objects.equal(this.domainName, other.domainName) && Objects.equal(this.diskQuota, other.diskQuota)
				&& Objects.equal(this.bandWidth, other.bandWidth) && Objects.equal(this.minBandwidth, other.minBandwidth)
				&& Objects.equal(this.maxConnection, other.maxConnection) && Objects.equal(this.maxEmail, other.maxEmail)
				&& Objects.equal(this.maxEmailAlias, other.maxEmailAlias) && Objects.equal(this.maxSubDomain, other.maxSubDomain)
				&& Objects.equal(this.maxFtp, other.maxFtp) && Objects.equal(this.apacheService, other.apacheService)
				&& Objects.equal(this.pureFtpdService, other.pureFtpdService) && Objects.equal(this.powerDnsServiceMaster, other.powerDnsServiceMaster)
				&& Objects.equal(this.powerDnsServiceSlave, other.powerDnsServiceSlave) && Objects.equal(this.catchallEmail, other.catchallEmail)
				&& Objects.equal(this.subDomains, other.subDomains);
	}

	@Override
	public int hashCode() {
		return Objects.hashCode(this.id, this.domainName, this.diskQuota, this.bandWidth, this.minBandwidth, this.maxConnection, this.maxEmail,
				this.maxEmailAlias, this.maxSubDomain, this.maxFtp, this.apacheService, this.pureFtpdService, this.powerDnsServiceMaster,
				this.powerDnsServiceSlave, this.catchallEmail, this.subDomains);
	}
}
